/**
 * 二维矩阵，只能向左右下三个方向走，每一步花1个时间
 * 地形不一样需要额外多花1个时间，问从左上到右下的最短时间
 * 标准的Dijkstra，不过不需要建显式图
 */
#include <bits/stdc++.h>
using namespace std;

#include <bits/extc++.h>
using namespace __gnu_pbds;

using llt = long long;
using vi  =vector<int>;
using pii = pair<int, int>;
using vvi = vector<vi>;
using vpii = vector<pii>;

struct _t{
    int r;
    int c;
    int w;
    _t(int a=0, int b=0, int cost=0):r(a),c(b),w(cost){}
    bool operator < (const _t & rhs) const {
        if(w != rhs.w) return w > rhs.w;
        if(r != rhs.r) return r > rhs.r;
        return c > rhs.c;
    }
};

int const INF = 0x3F4F5F6F;
int const DR[] = {0, 0, 1};
int const DC[] = {-1, 1, 0};

int N, M;
vvi Board;
vvi D;

__gnu_pbds::priority_queue<_t> Q;

int proc(){
    D.assign(N, vi(M, INF));
    Q.clear();
    Q.push({0, 0, D[0][0] = 0});
    vvi flag(N, vi(M, 0));

    while(1){
        while(not Q.empty() and flag[Q.top().r][Q.top().c]) Q.pop();
        if(Q.empty()) break;

        auto h = Q.top(); Q.pop();

        for(int nr,nc,i=0;i<3;++i){
            nr = h.r + DR[i];
            nc = h.c + DC[i];
            if(0 <= nr and nr < N and 0 <= nc and nc < M and not flag[nr][nc]){
                int diff = Board[h.r][h.c] != Board[nr][nc] ? 2 : 1;
                int cost = diff + h.w;
                if(cost < D[nr][nc]){
                    Q.push({nr, nc, D[nr][nc] = cost});
                }
            } 
        }
    }

    return D[N - 1][M - 1];
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
    int nofkase = 1;
    // cin >> nofkase;
    while(nofkase--){
        cin >> N >> M;
        Board.assign(N, vi(M, 0));
        for(auto & a : Board)for(auto & i : a)cin >> i;
        cout << proc() << "\n";
    }
    return 0;
}